package com.linrung.sf.scheduler.zwwx;

import cn.hutool.core.date.DateUtil;
import cn.hutool.setting.Setting;
import com.linrung.core.cache.ICacheClient;
import com.linrung.core.utils.JsonUtils;
import com.linrung.core.utils.StringTools;
import com.linrung.sf.scheduler.zwwx.entity.*;
import com.linrung.sf.scheduler.zwwx.jms.ZWWXMsgProductorService;
import com.linrung.sf.scheduler.zwwx.service.ZwwxMessageSendService;
import com.linrung.platform.job.jobConfig.JobConfigEntity;
import com.linrung.scheduler.core.AbstractJobBusinessService;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import java.nio.charset.StandardCharsets;
import java.util.*;

@Service(value="ZwwxMsgSyncService")
public class ZwwxMsgSyncService extends AbstractJobBusinessService{
	
	private static Logger logger = Logger.getLogger(ZwwxMsgSyncService.class);
	public static String ZWWX_JOB_PARAM_CACHE_KEY = "ZWWX_JOB_PARMA"; //政务微信定时任务，参数缓存KEY
	public static final String ZWWX_SF_CACHE_TOKEN = "ZWWX_SF_CACHE_TOKEN:";//政务微信接口token缓存KEY
	private static boolean isLoadJobParam = false;
	public static int RESULT_STATUS_SUCCESS = 1; //发送成功
	public static int RESULT_STATUS_FAIL = 0; //发送失败
	public static int RESULT_STATUS_API_ERROR = 2; //发送接口异常
	public static int RESULT_STATUS_USER_NOT_FIND = 3; //接收用户的粤政易统一平台用户ID没同步
	public static int RESULT_STATUS_API_SYS_BUSY = 4; //发送时系统繁忙

	@Autowired
	private ZwwxMessageSendService zwwxMessageService;
	@Autowired
	private ICacheClient cacheClient;
	@Autowired
	private ZWWXMsgProductorService zwwxMsgProductorService;

	@Autowired
	@Qualifier("jdbcTemplate")
	private JdbcTemplate jdbcTemplate;

	private static final String MESSAGE_URL = "URL";
	private static final String MESSAGE_CONTENT = "CONTENT";
	/**
	 * 已获取的accessToken
	 */
	private Map<String, AccessEntity> accessTokenMap = new HashMap<String,AccessEntity>();
	
	//消息来源编码分支
	private String sourceCodeFork = null;
	//消息来源子编码映射
	private String sourceCodeSubMapping = null;
	//获取政务微信消息打开链接
	private Integer agentId = null;
	private String openLink = null;
	private String roleLink = null;
	
	private int successCount = 0;
	private int noUserWxIdCount = 0;
	private int otherErrorCount = 0;

	private Setting _setting = null;

	@Override
	public String execute(JobConfigEntity jobConfig) {
		long time1 = System.currentTimeMillis();
		logger.info("开始推送政务微信消息==============");
		
		//参数验证		
		String zwwxTokenUnApiUrl = jobConfig.getParams().get("REMOTE_URL");
		if(StringUtils.isBlank(zwwxTokenUnApiUrl)) {
			logger.error("请在定时任务参数配置中配置政务微信Token获取统一API地址【REMOTE_URL】参数");
			return null;
		}
		//http://19.15.0.200:8080/ebus/yzyapi/cgi-bin/message/send?access_token=%s
		String sendUrl = jobConfig.getParams().get("SENDURL");
		if(StringUtils.isBlank(sendUrl)) {
			logger.error("请在定时任务参数配置中配置【SENDURL】参数");
			return null;
		}
		openLink = jobConfig.getParams().get("OPENLINK");
		if(StringUtils.isBlank(openLink)) {
			logger.error("请在定时任务参数配置中配置【OPENLINK】参数");
			return null;
		}
		agentId = Integer.parseInt(jobConfig.getParams().get("AGENTID"));
		if(agentId==null) {
			logger.error("请在定时任务参数配置中配置【AGENTID】参数");
			return null;
		}
		roleLink = jobConfig.getParams().get("ROLELINK");
		if(roleLink==null) {
			logger.error("请在定时任务参数配置中配置【ROLELINK】参数");
			return null;
		}

		accessTokenMap.clear();
		successCount = 0;
		noUserWxIdCount = 0;
		otherErrorCount = 0;

		if(isLoadJobParam == false) {
			isLoadJobParam = true;
			cacheClient.set(ZWWX_JOB_PARAM_CACHE_KEY, jobConfig);
		}

		try {
			if(_setting == null){
				_setting = new Setting("jms.template.setting");
			}
			if(_setting.isEmpty()){
				logger.error("setting配置为空！");
			}
		}catch (Exception e){
			logger.error("取setting配置："+e.getMessage(), e);
		}finally {
			sendMessageGroup(jobConfig);
		}
		long time2 = System.currentTimeMillis();
		logger.info(String.format("结束推送政务微信消息==============，共花费 = %d ms, 成功发送JMS = %d, 用户没绑定微信失败 = %d, 其他验证性错误 = %d", time2-time1, successCount, noUserWxIdCount, otherErrorCount));
		return null;
	}
	
	/**
	 * 推送待办的消息
	 * @param jobConfig
	 */
	private void sendMessageGroup(JobConfigEntity jobConfig){
		//生成待发送消息
		zwwxMessageService.genAppealNodeTodo();
		zwwxMessageService.genBackAppealNodeTodo();
		zwwxMessageService.genWorkTaskTodo();
		zwwxMessageService.genAnnounce();
		zwwxMessageService.genPreAppealTodo();

		//获取待发消息
		List<ZwwxMessageEntity> msgList = zwwxMessageService.loadNoDealMessageList();

		int msgListSize = 0;
		if(msgList != null) {
			msgListSize = msgList.size();
		}
		logger.info(String.format("本次要发送的政务微信消息总条数 = %d", msgListSize));

		//jms发送列表
		List<JMSSendParamVO> sendList = new ArrayList<JMSSendParamVO>();
		//发送消息
		for(ZwwxMessageEntity msgr : msgList){
			//发送JMS消息
			String pfMsgReceiveId = msgr.getId();
			if(StringUtils.isBlank(msgr.getReceiverSyncUserId()) || msgr.getReceiverSyncUserId().equals("-99")){
				logger.error(msgr.getReceiverId() + "用户，未同步粤政易用户ID，无法推送！");
				noUserWxIdCount++;
				zwwxMessageService.updateReceiverWxSendStateById(msgr.getId(), "2");
				continue;
			}
			if(StringUtils.isBlank(msgr.getTitle())) {
				otherErrorCount++;
				logger.error(msgr.getReceiverId() + ",标题为空了，无法推送！");
				zwwxMessageService.updateReceiverWxSendStateById(msgr.getId(), "2");
				continue;
			}
			if(StringUtils.isNotEmpty(msgr.getReceiverSyncUserId())){
				String zwsxMsgcontent = null;
				TextCardEntity card = null;
				if(Objects.equals(msgr.getMsgType(), "0")){
					card = setAnnounceCard(msgr);
				}else{
					card = setCard(msgr);
				}

				//卡片消息
				//if(msgr.getMessageType()==1) {
					MessageEntity message = new MessageEntity();
					message.setTouser(msgr.getReceiverSyncUserId());
					message.setToparty("");
					message.setMsgtype(ZwwxMsgType.textCard.getValue());
					message.setTotag("");
					message.setAgentid(agentId);
					card.setUrl(String.format(openLink, message.getTouser(), "need", msgr.getBusinessKeyId()));
					message.setTextcard(card);
					zwsxMsgcontent = JsonUtils.converJsonStr(message, null);
				//文本消息
				/**
				}else{
					TextMessageEntity message = new TextMessageEntity();
					message.setTouser(msgr.getReceiverSyncUserId());
					message.setToparty("");
					message.setMsgtype(ZwwxMsgType.text.getValue());
					message.setTotag("");
					message.setAgentid(agentId);
					JSONObject text = new JSONObject();
					text.put("content",card.getDescription());
					message.setText(text);
					zwsxMsgcontent = JsonUtils.converJsonStr(message, null);
				}**/

				JMSSendParamVO jmsSendParamVO = new JMSSendParamVO();
				jmsSendParamVO.setPfMsgReceiveId(pfMsgReceiveId);
				jmsSendParamVO.setZwsxMsgcontent(zwsxMsgcontent);
				sendList.add(jmsSendParamVO);
				zwwxMessageService.updateReceiverWxSendStateById(msgr.getId(), "1");
				successCount++;
			}
		}
		//等上面的数据库操作完成，一次行发送JMS，保证消费者消费时间长，数据库锁太久
		zwwxMsgProductorService.send(sendList);
	}

	/**
	 * 设置卡面内容
	 * @param msgr
	 * @return
	 */
	private TextCardEntity setCard(ZwwxMessageEntity msgr){
		TextCardEntity card = new TextCardEntity();
		//卡片消息
		//if(msgr.getMessageType()==1){
			Map<String, String> templates = _setting.getMap("COMMON.YPA");
			String tpl = StringTools.getValue(templates.get("template"), null);
			String tplLight = StringTools.getValue(templates.get("templateLight"), null);
			String type = StringTools.getValue(templates.get("type"), null);
			String description = formatDescription(tpl, msgr.getTitle(), msgr.getSource(), msgr.getSenderDept(), msgr.getRemindTime());
			card.setTitle(type);
			card.setDescription(description);
		/**
		}else {
			Map<String, String> templates = _setting.getMap("COMMON.YPA.TEXT");
			String tpl = StringTools.getValue(templates.get("template"), null);
			String description = formatDescription(tpl, msgr.getTitle(), msgr.getSource(), msgr.getSenderDept(), msgr.getRemindTime());
			card.setDescription(description);
		}**/
		return card;
	}


	/**
	 * 设置卡面内容
	 * @param msgr
	 * @return
	 */
	private TextCardEntity setAnnounceCard(ZwwxMessageEntity msgr){
		TextCardEntity card = new TextCardEntity();
		//卡片消息
		//if(msgr.getMessageType()==1){
		Map<String, String> templates = _setting.getMap("COMMON.YPA.ANNOUNCE");
		String tpl = StringTools.getValue(templates.get("template"), null);
		String tplLight = StringTools.getValue(templates.get("templateLight"), null);
		String type = StringTools.getValue(templates.get("type"), null);
		String description = formatDescription(tpl, msgr.getTitle(), msgr.getSender(), msgr.getSenderDept(), msgr.getRemindTime());
		card.setTitle(type);
		card.setDescription(description);
		return card;
	}

	/**
	 * 计算卡片消息的字节，不能超过512, 不然优先截掉标题的字数
	 * @param tpl
	 * @param title
	 * @param subTitle
	 * @param sender
	 * @param time
	 * @return
	 */
	private String formatDescription(String tpl, String title, String subTitle, String sender, Date time){
		return formatDescriptionFormat(tpl, title, subTitle, sender, time, null);
	}
	private String formatDescriptionFormat(String tpl, String title, String subTitle, String sender, Date time, String format){
		String timeStr = time != null ? DateUtil.format(time, StringUtils.isNotBlank(format) ? format : "yyyy-MM-dd HH:mm") : "";
		String description = String.format(tpl, title, subTitle, sender, timeStr);

		String tempTitle = "";
		int total = description.getBytes(StandardCharsets.UTF_8).length;
		//原定最大字节512，但行数超过六行，也会隐藏后面的日期信息，所以限到414
		while (total > 414){
			int etc = (total - 414 + 3) / 4;
			title = title.substring(0, title.length() - etc - 3);
			tempTitle = title + "...";
			description = String.format(tpl, tempTitle, subTitle, sender, timeStr);
			total = description.getBytes(StandardCharsets.UTF_8).length;
		}
		return description;
	}
	
}
